package Year2021;

import java.math.BigInteger;

/**
 Question：
 小蓝有一个超大的仓库，可以摆放很多货物。
 现在，小蓝有 n 箱货物要摆放在仓库，每箱货物都是规则的正方体。小蓝规定了长、宽、高三个互相垂直的方向，每箱货物的边都必须严格平行于长、宽、高。
 小蓝希望所有的货物最终摆成一个大的长方体。即在长、宽、高的方向上分别堆 L、W、H 的货物,满足 n = L×W×H。
 给定 n，请问有多少种堆放货物的方案满足要求。
 例如，当 n = 4 时，有以下 6种方案：1×1×4、1×2×2、1×4×1、2×1×2、2 × 2 × 1、4 × 1 × 1
 请问，当 n = 2021041820210418（注意有 1616 位数字）时，总共有多少种方案？

 Solve：
 注意到 n = L×W×H这一条件，既然L、W、H相乘为n，那么L、W、H肯定都是n的因子。所以只要把n的全部因子找出来，然后找三个因子去充当长宽高，三重for循环就解决了。
 其实这道题有了1×1×4、1×4×1、4 × 1 × 1算不同情况这一隐性条件以后就简单了不少。

 */
public class 货物摆放 {
    public static void main(String[] args) {
        //System.out.println("结果："+货物摆放_学习());
        System.out.println("结果："+货物摆放_提交());
    }
    public static int 货物摆放_提交(){
        Long a[] = new Long[20000],n = 2021041820210418L; //存放数字的因子.....超大数的表示方法，后面加一个L：其范围是 -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 (-2^63 to 2^63 - 1)
        int count = 0,res = 0;
        for (Long i = 1L; i <= Math.sqrt(n); i++) { // 求一个数的全部因子
            if(n % i == 0){
                a[++count] = i;
                if( i * i != n)
                    a[++count] = n / i;

            }
        }
        for (int i = 1; i <= count; i++) {
            for (int j = 1; j <= count; j++) {
                for (int k = 1; k <= count; k++) {
                    if(a[i] * a[j] * a[k] == n)
                        res++;
                }
            }
        }
        return res;
    }
    public static int 货物摆放_学习(){
        Long a[] = new Long[20000],n = 2021041820210418L; //存放数字的因子.....超大数的表示方法，后面加一个L：其范围是 -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 (-2^63 to 2^63 - 1)
        int count = 0,res = 0;
        for (Long i = 1L; i <= Math.sqrt(n); i++) { // 求一个数的全部因子（注意边界条件）
            if(n % i == 0){
                a[++count] = i;
                if( i * i != n) // 控制可以正好开根号的数字重复计算
                    a[++count] = n / i;

            }
        }
        for (int i = 1; i <= count; i++)
            System.out.println(a[i]+"\t");
        System.out.println("因子个数："+count);
        for (int i = 1; i <= count; i++) {
            for (int j = 1; j <= count; j++) {
                for (int k = 1; k <= count; k++) {
                    if(a[i] * a[j] * a[k] == n)
                        res++;
                }
            }
        }
        return res;
    }
}
